'''
Created on Aug 16, 2010

@author: dexen
'''
import os
import csv
import string
import datetime

from sim_lib import radiancelink
from sim_lib import energypluslink
from sim_lib import daysimlink

class Surface(object):
    def __init__(self, name, points, material):
        self.name = name
        self.points = points
        self.material = material
    
class RadGeom(object):
    def __init__(self, ):
        self.surfaces = []
        self.total_sensor_pts = None
        self.result_file = None
        self.sensor_file_path = None
        self.rad_file_path = None
        self.hea_result = None
        self.hea_filename = None
        self.direction = None
        self.rad_mat_file = None  
             
    def add_sensor_points(self, sensor_pt_list, direction):
        self.total_sensor_pts = sensor_pt_list
        self.direction = direction
        
    def add_sky(self, gensky_command, sky_colour, ground_colour):
        self.gensky_command = gensky_command
        self.sky_colour = sky_colour
        self.ground_colour = ground_colour
        
    def create_rad(self, basefile_path, filename, interior = True):
        radout = os.path.join(basefile_path, filename)
        rad_file_path = os.path.join(radout, filename + "_out.rad")
        #CREATE THE RADOUT DIRECTORY FOR STORING THE OUTPUT FILE 
        if not os.path.isdir(radout):
            os.mkdir(radout)
        #CREATE THE .RAD FILE 
        rad_building_data = []
        rad_file = open(rad_file_path,  "w")
        for surface in self.surfaces:
            if interior == True:
                rad_data = surface.rad()
            else:
                rad_data = surface.rad(interior = False)
            rad_building_data.append(rad_data)
            
        for data in rad_building_data:
            rad_file.write(data)
        rad_file.close()
        
        #CREATE SENSOR FILE 
        sensor_file_path = os.path.join(radout, filename + "_out.pts")
        sensor_file = open(sensor_file_path,  "w")
        sensor_pts_data = radiancelink.write_sensor_file(self.total_sensor_pts, self.direction)
        sensor_file.write(sensor_pts_data)
        sensor_file.close()
        
        self.radout = radout
        self.sensor_file_path = sensor_file_path
        self.rad_file_path = rad_file_path 
        self.rad_mat_file = os.path.join(basefile_path, filename + ".mat")
        
        if self.gensky_command != None:
            #CREATE SKY FILE
            sky_file_path = os.path.join(radout, filename + "_sky.rad")
            sky_file = open(sky_file_path,  "w")
            gensky = self.gensky_command
            sky_glow = radiancelink.write_glow("sky_glow", self.sky_colour)
            grd_glow = radiancelink.write_glow("ground_glow", self.ground_colour)
            sky_source = radiancelink.write_source("sky", "sky_glow", (0,0,1))
            grd_source = radiancelink.write_source("ground", "ground_glow", (0,0,-1))
            sky_data = gensky + "\n\n" + sky_glow + "\n\n" + grd_glow + "\n\n" + sky_source + "\n\n" + grd_source
            sky_file.write(sky_data)
            sky_file.close()
            
            self.sky_file_path = sky_file_path
            
            return radout, sensor_file_path, rad_file_path, sky_file_path
        else:
            return radout, sensor_file_path, rad_file_path
    
    def execute_oconv(self, basefile_path, basefilename, filename): 
        create_rad = self.create_rad(basefile_path, filename)
        radout = create_rad[0]
        rad_file_path = create_rad[2]
        #EXECUTE OCONV 
        oconv_file = os.path.join(radout, filename + "_out.oconv")
        material_file = os.path.join(basefile_path, basefilename + ".mat")
        sky_file = create_rad[3]
        command = "oconv " + material_file + " "\
        + sky_file + " " + rad_file_path +\
        " " + ">" + " " + oconv_file
        os.system(command)
        self.oconv_file = oconv_file 
    
    def execute_rtrace(self, filename, dict_parm):
        if self.oconv_file == None:
            raise Exception
        #execute rtrace 
        sensors_file = self.sensor_file_path
        oconv_file = self.oconv_file
        radout = self.radout
        result_file = os.path.join(radout, filename + "_out.txt")
        command = "rtrace -h -w -I+ -ab " +  dict_parm["ab"] + " -aa " + dict_parm["aa"] +\
        " -ar " + dict_parm["ar"] + " -ad " + dict_parm["ad"] + " -as " + dict_parm["as"] +\
        " " + oconv_file + " " + " < " + sensors_file +\
        " " + " > " + " " + result_file 

        os.system(command)
        self.result_file = result_file 
        
    def execute_rvu(self, vp, vd, dict_parm):
        if self.oconv_file == None:
            raise Exception
        #execute rvu
        oconv_file = self.oconv_file
        operating_sys = os.name
        if operating_sys == "posix":
            command = "rvu -vp " + vp + " -vd " + vd +\
            " -ab " + dict_parm["ab"] + " -aa " + dict_parm["aa"] +\
            " -ar " + dict_parm["ar"] + " -ad " + dict_parm["ad"] + " -as " + dict_parm["as"] +\
            " -pe " + dict_parm["exp"] + " " + oconv_file + " &"
        elif operating_sys == "nt":
            command = "rview -vp " + vp + " -vd " + vd +\
            " -ab " + dict_parm["ab"] + " -aa " + dict_parm["aa"] +\
            " -ar " + dict_parm["ar"] + " -ad " + dict_parm["ad"] + " -as " + dict_parm["as"] +\
            " -pe " + dict_parm["exp"] + " " + oconv_file + " &"
        
        os.system(command)
         
    def execute_rpict(self, filename, x_resolution, y_resolution, vp, vd, dict_parm):
        if self.oconv_file == None:
            raise Exception
        #execute rpict
        oconv_file = self.oconv_file
        radout = self.radout
        result_filepath = os.path.join(radout,"images")
        if not os.path.isdir(result_filepath):
            os.mkdir(result_filepath)
        result_file = os.path.join(result_filepath, filename)
        command = "rpict -x " + x_resolution + " -y " + y_resolution + " -vp " + vp +\
         " -vd " + vd +\
         " -ab " +  dict_parm["ab"] + " -aa " + dict_parm["aa"] +\
         " -ar " + dict_parm["ar"] + " -ad " + dict_parm["ad"] + " -as " + dict_parm["as"] +\
         " -i " + oconv_file + " > " + result_file + "out_i.hdr" 
          
        command2 = "rpict -x " + x_resolution + " -y " + y_resolution + " -vp " +\
         vp + " -vd " + vd +\
         " -ab " +  dict_parm["ab"] + " -aa " + dict_parm["aa"] +\
        " -ar " + dict_parm["ar"] + " -ad " + dict_parm["ad"] + " -as " + dict_parm["as"] +\
         " " + oconv_file + " > " + result_file + "out.hdr"
          
        command3 = "pfilt -e " + dict_parm["exp"] + " " + result_file + "out_i.hdr" + " > " +\
         result_file + "out_i_filt.hdr"
        command4 = "pfilt -e " + dict_parm["exp"] + " " + result_file + "out.hdr" + " > " +\
         result_file + "out_filt.hdr"

        os.system(command)  
        os.system(command2) 
        os.system(command3)
        os.system(command4)
        
    def execute_falsecolour(self,i_basefilename, l_basefilename, filename, range_max, 
                            range_division, illuminance = True):
        radout = self.radout
        image_filepath = os.path.join(radout, "images")
        i_base_image_path = os.path.join(image_filepath, i_basefilename)
        l_base_image_path = os.path.join(image_filepath, l_basefilename)
        falsecolour_path = os.path.join(image_filepath, "falsecolour")
        if not os.path.isdir(falsecolour_path):
            os.mkdir(falsecolour_path)
        result_file_path = os.path.join(falsecolour_path, filename + "falsecolour")
        if illuminance == True:
            command = "falsecolor -i " + i_base_image_path + " -p " +\
             l_base_image_path + " -cl -n " + range_division + " -s " + range_max +\
             " -l lux > " + result_file_path + "_illum.hdr"
        else:
            command = "falsecolor -ip " + l_base_image_path +\
             " -cl -n " + range_division + " -s " + range_max +\
             " -l cd/m2 > " + result_file_path + "_luminance.hdr"
        os.system(command)     
        
    def eval_rad(self, result_category):
        if self.result_file == None:
            raise Exception
        
        illum_results = open(self.result_file, "r")
        illum_res_list = []
        irradiance_list = []
        for illum_result in illum_results:
            words  = illum_result.split()
            numbers = map(float, words)
            #INSOLATION RESULTS 
            irradiance = round((0.265 * numbers[0]) + (0.670 * numbers[1]) + (0.065 * numbers[2]), 1)
            irradiance_list.append(irradiance)
            #ILLUMINANCE RESULTS            
            illuminance = irradiance * 179
            illum_res_list.append(illuminance)
            
        if result_category == "illuminance":
            return illum_res_list  
        if result_category == "irradiance":
            return irradiance_list
        
    def execute_hea(self, basefile_path, basefilename, filename, daysim_dir, weather_filename,
                    zone_area, occupancy_start, occupancy_end, min_illum_level):
        if self.sensor_file_path == None or self.rad_file_path == None:
            raise NameError("run .create_rad function before running .execute_hea function")
        
        #CREATE THE NECCESSARY FOLDERS FOR THE OUTPUT OF THE VARIOUS RESULTS
        heaout = os.path.join(basefile_path, filename + "/")
        hea_file_path = os.path.join(heaout, filename + "_out.hea")
        
        if not os.path.isdir(heaout):
            os.mkdir(heaout)
        sub_hea_folders = ["pts", "rad", "res","tmp", "wea"]
        for folder in range(len(sub_hea_folders)):
            sub_hea_folder = sub_hea_folders[folder]
            sub_hea_folders_path = os.path.join(heaout,sub_hea_folder)
            if not os.path.isdir(sub_hea_folders_path):
                os.mkdir(sub_hea_folders_path)
            if os.path.isdir(sub_hea_folders_path):
                files_in_dir = os.listdir(sub_hea_folders_path)
                for file in files_in_dir:
                    rmv_path = os.path.join(sub_hea_folders_path, file)
                    os.remove(rmv_path)
        
        #APPEND THE BASEFILE 
        base_filepath = os.path.join(basefile_path, basefilename + ".hea") 
        base_file = open(base_filepath, "r")
        base_stuff = base_file.read()
        base_file.close()
        hea_data = []
        hea_data.append(base_stuff)
        
        #WRITE THE HEA INFORMATION 
        tmp_dir = os.path.join(heaout, "tmp/")
        proj_info = daysimlink.write_proj_info(filename, heaout, tmp_dir)
        hea_data.append(proj_info)
        
        #WRITE THE ZONE AREA AND USER DESCRIPTION
        zone_size = daysimlink.write_zone_area(zone_area)
        hea_data.append(zone_size)
        user_description = daysimlink.write_user_description(occupancy_start, 
                                                             occupancy_end, 
                                                             min_illum_level)
        hea_data.append(user_description)
        
        #WRITE THE WEATHER DATA 
        wea_file_dir = os.path.join(daysim_dir,"wea", weather_filename) # in order to change the weather file input the 60min .wea dir, do the conversion from epw to wea using execute_epw2wea(bin_dir, source_file, destination_file)
        short_wea_name = weather_filename + "_5min.wea" # change the output .wea name respectively 
        weather_data = daysimlink.write_weather_data(wea_file_dir, 0.2, short_wea_name)
        hea_data.append(weather_data)
        
        #WRITE THE GEOMETRY INFO
        sensor_file_path = self.sensor_file_path 
        rad_file_path = self.rad_file_path 
        rad_file_dir_list = [self.rad_mat_file, rad_file_path]
        geometry_data = daysimlink.write_geometry_info(filename, sensor_file_path, rad_file_dir_list)
        hea_data.append(geometry_data)
        
        #WRITE THE RESULTS INFO
        result_data = daysimlink.write_result_file(filename)
        hea_data.append(result_data)
        
        #WRITE THE RESULT FILE 
        hea_file = open(hea_file_path,  "w")
        for data in hea_data:
            hea_file.write(data)
        hea_file.close()
        
        #EXECUTE DAYSIM
        bin_dir = os.path.join(daysim_dir,"bin") 
        os.chdir(bin_dir)
        command1 =  "./ds_shortterm " +  hea_file_path
        os.system(command1)
        command2 = "./radfiles2daysim " +  "'" + hea_file_path +"'" + " -g -m -d"
        os.system(command2)
        command3 = "./gen_dc " +  "'" + hea_file_path +"'"
        os.system(command3)
        command4 = "./ds_illum " +  "'" + hea_file_path +"'" 
        os.system(command4)
        command5 = "./gen_directsunlight " +  "'" + hea_file_path +"'" 
        os.system(command5)
        command6 = "./ds_autonomy " +  "'" + hea_file_path +"'" 
        os.system(command6)
        
        self.hea_result = os.path.join(heaout, "res")
        self.hea_filename = filename
        
    def eval_hea(self):
        if self.hea_result == None or self.hea_filename == None :
            raise Exception
        da_path = os.path.join(self.hea_result,self.hea_filename + ".da")
        da_results = open(da_path, "r")
        da_result_stuff = da_results.readlines()
        num_da_list = []
        #daysim results processing average the DA
        for line in range(len(da_result_stuff)-2): 
            lines =  da_result_stuff[2+line][78:83] 
            numbers_da = float(lines)
            num_da_list.append(round(numbers_da, 1))
        return num_da_list
    
class RadSurface(Surface):
    def __init__(self, name, points, material, radgeom):
        super(RadSurface, self).__init__(name,  points, material)
        self.radgeom = radgeom
        radgeom.surfaces.append(self)
        
    def rad(self, interior = True):
        name = self.name
        material = self.material
        points = self.points[:]
        if interior == True:
            points.reverse()
        return radiancelink.write_surface(name, material, points)
        
class IdfGeom(object):
    
    def __init__(self):
        self.zones = []
        self.simparms = []
        self.outputvars = []
        self.outputmeter = []
        self.buildingshades = []
        self.building_data = None
        self.result_file = None
        self.filename = None
        
    def add_terrain(self, terrain):
        self.terrain = terrain
        
    def execute_idf(self, basefile_path, basefilename, filename, weather_file, enrgy_dir = "", weather_dir = ""):
        total_srfs= []
        total_srfs_pt = []
        total_sub = []
        same_srfs= []
        
        #SEARCH FOR OVERLAPPING surfaces
        for zone in self.zones:
            for srf in zone.surfaces:
                total_srfs.append(srf)
            for subsrf in zone.subsurfaces:
                total_sub.append(subsrf)
        for total_srf in total_srfs:
            srf_pt = total_srf.points[:]
            srf_pt.sort()
            total_srfs_pt.append(srf_pt)
            
        counter = 0
        for total_srf in total_srfs:
            #print total_srf.name, "all the names"
            for num_srf in range(len(total_srfs)):
                if num_srf <= len(total_srfs)-(2+counter):
                    total_srf_ref = total_srf.points[:]
                    total_srf_ref.sort()
                    total_srf_comp = total_srfs[num_srf+1+counter].points[:]
                    total_srf_comp.sort()
                    if total_srf_ref == total_srf_comp:
                        total_srfs[num_srf +(1+counter)].boundary = "Surface" 
                        total_srfs[num_srf +(1+counter)].boundary_obj = total_srf.name 
                        total_srfs[num_srf +(1+counter)].sun_exp = "NoSun"
                        total_srfs[num_srf +(1+counter)].win_exp = "NoWind"
                        same_srfs.append(total_srfs[num_srf +(1+counter)])
                        total_srf.boundary = "Surface" 
                        total_srf.boundary_obj = total_srfs[num_srf +(1+counter)].name 
                        total_srf.sun_exp = "NoSun"
                        total_srf.win_exp = "NoWind"
                        same_srfs.append(total_srf)
                        break
            counter +=1
            
        #GET ALL THE DATA FROM THE OBJECTS AND APPEND IT INTO THE TEXT FILE 
        zones_data = ""
        total_srfs_data = ""
        total_sub_data = ""
        sims_data = ""
        buildingshade_data = ""
        vars_data = ""
        meter_data = ""
        terrain_data = ""
        
        if self.terrain == None:
            return Exception
        terrain_data = energypluslink.write_ep_building(self.terrain)
        
        for simparm in self.simparms:
            sims_data = sims_data + simparm.idf()
        for outputvar in self.outputvars:
            vars_data = vars_data + outputvar.idf()
        for outputmeter in self.outputmeter:
            meter_data = meter_data + outputmeter.idf()
        for buildingshade in self.buildingshades:
            buildingshade_data = buildingshade_data + buildingshade.idf()
        for zone in self.zones:
            zones_data = zones_data + zone.idf()
        for srfs in total_srfs:
            total_srfs_data = total_srfs_data + srfs.idf()
        for subsrfs in total_sub:
            total_sub_data = total_sub_data + subsrfs.idf()
        building_data = terrain_data + sims_data + zones_data + total_srfs_data +\
         total_sub_data + vars_data + meter_data + buildingshade_data
        
        #CREATE THE TEXT FILE 
        idfout = os.path.join(basefile_path, filename)
        idf_file_path = os.path.join(idfout, filename + "_out.idf")
        if not os.path.isdir(idfout):
            os.mkdir(idfout)
        idf_data = []
        base_idf_file = os.path.join( basefile_path, basefilename + ".idf")
        
        #read all the stuff in the base idf file 
        base_idf_file = open(base_idf_file,  "r")
        base_stuff = base_idf_file.read()
        base_idf_file.close()
        idf_data.append(base_stuff)
        for _ in range(10):
            idf_data.append("! ======================================== \n")
            
        #APPEND THE BUILDING DATA
        idf_data.append(building_data)
        idf_file = open(idf_file_path,  "w")
        for data in idf_data:
            idf_file.write(data)
        idf_file.close()
        
        #EXECUTE ENERGYPLUS 
        #prev_dir = os.getcwd()
        #target_dir = os.path.join("/home", "dexen", "EnergyPlus", "EnergyPlus-5-0-0", "bin")
        #print "The energyplus dir is", target_dir
        #os.chdir(target_dir)
        print "IDF FILE PATH is", idf_file_path, "............................."
        operating_sys = os.name
        if operating_sys == "posix":
            command = "runenergyplus " +  idf_file_path + " " + weather_file +  " > ep_out.txt"
            os.system(command)
            f = open("ep_out.txt", "r")
            print f.read()
            f.close()
            self.result_file = os.path.join(idfout, "Output")

        elif operating_sys == "nt":
            #create bat file with command in it
            sim_file = os.path.join(idfout, filename + "_out.bat")
            idf_file_path_win = os.path.join(idfout, filename + "_out")
            idf_res_output_folder = os.path.join(idfout, "Output" )
            if not os.path.isdir(idf_res_output_folder):
                os.mkdir(idf_res_output_folder)
            idf_res_file_path = os.path.join(idf_res_output_folder, filename + "_out")
            weather_file_path = os.path.join(weather_dir, weather_file )
            sim = open(sim_file,  "w")
            sim.write(enrgy_dir[0:2] + "\n")
            sim.write("cd " + enrgy_dir + "\n")
            sim.write("Epl-run.bat " + '"' + idf_file_path_win + '" ' + '"' + idf_res_file_path + '" ' + 'idf' +\
                     ' "' + weather_file_path + '" ' + 'EP N nolimit N N')
            sim.close()
            command = sim_file
            os.system(command)
            self.result_file = os.path.join(idfout, "Output")
        
        
        self.filename = filename
        #os.chdir(prev_dir)
        
        
    def eval_csv(self):
        if self.result_file == None:
            raise Exception
        #check the number days the simulation ran for 
        run_period_days = []
        for sim in self.simparms:
            s_mth = int(sim.s_mth)
            s_day = int(sim.s_day)
            e_mth = int(sim.e_mth)
            e_day = int(sim.e_day)
            start = datetime.date(2010, s_mth, s_day)
            end =  datetime.date(2010, e_mth, e_day)
            diff = end - start
            run_period_days.append(diff.days)
            
        total_days = sum(run_period_days)
        self.simdays = total_days
        
        #check thru the csv file 
        result_path = os.path.join(self.result_file, self.filename + "_out" + ".csv")
        f = open(result_path, "r")
        reader = csv.reader(f, delimiter=",", quotechar='"')
        #append the csv file into a row list 
        content = []
        for row in reader:
            s_row = []
            for r in row:
                s_row.append(r.strip())
            content.append(s_row)
        f.close
        #from the row list append it to become the column list 
        content2 = []
        cols = len(content[0])
        rows = len(content)
        for col in range(cols):
            col_data = []
            for row in range(rows):
                try:
                    col_data.append(content[row][col])
                except:
                    col_data.append(None)
            content2.append(col_data)
        self.content = content2
            
    def eval_idf(self, result_category, display):
        if self.content == None:
            raise Exception
        content = self.content
        total_simdays = self.simdays
        
        #======================================================================
        #FOR ENERGY TRANSFER BUILDING LEVEL 
        if result_category == "energytransfer":
            res_list = []
            for c in content:
                if c[0] == "Cooling:EnergyTransfer [J](RunPeriod)":
                    c_enrgy = c[1:]
                elif c[0] == "Heating:EnergyTransfer [J](RunPeriod)":
                    h_enrgy = c[1:]
                    
            c_enrgy = sum(map(float,c_enrgy))
            h_enrgy = sum(map(float,h_enrgy))
            t_enrgy = c_enrgy + h_enrgy
            
            if display == "daily":
                total = t_enrgy / total_simdays
                total = total * 2.77777777777778E-07 # convert from J to KWh

            else:
                total = t_enrgy * 2.777777777777787E-07 # convert from J to KWh
                
            res_list.append(total)
            return res_list
        
        #======================================================================
        #======================================================================

        #FOR ENERGY TRANSFER ZONE LEVEL 
        if result_category == "z_sys_sensible_cooling":
            counter = 0
            res_list = {}
            res_list["att_name"] ="Zone/Sys_Sensible_Cooling Energy[KWh]"
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Zone/Sys Sensible Cooling Energy [J](RunPeriod)":
                        zone_name  = string.lower(c[0].split(":")[0])
                        if display == "daily":
                            value = sum(map(float,c[1:]))/total_simdays
                            value = value*2.77777777777778E-07 # convert from J to KWh
                        else:
                            value = sum(map(float,c[1:]))
                            value = value*2.77777777777778E-07 # convert from J to KWh
                        res_list[zone_name] = value
            
                counter =+1
            return res_list
        #======================================================================
        if result_category == "z_sys_sensible_heating":
            counter = 0
            res_list ={}
            res_list["att_name"] ="Zone/Sys_Sensible_Heating Energy[KWh]"
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Zone/Sys Sensible Heating Energy [J](RunPeriod)":
                        zone_name  = string.lower(c[0].split(":")[0])
                        if display == "daily":
                            value = sum(map(float,c[1:]))/total_simdays
                            value = value*2.77777777777778E-07 # convert from J to KWh
                        else:
                            value = sum(map(float,c[1:]))
                            value = value*2.77777777777778E-07 # convert from J to KWh
                        res_list[zone_name] = value
                        
                counter =+1
            return res_list
        
        #======================================================================
        #======================================================================

        #FOR SRF EXT CATEGORY 
        if result_category == "sol_incident":
            counter = 0
            res_list ={}
            res_list["att_name"] ="Surface_Ext_Solar_Incident"
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Solar Incident[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        if display == "daily":
                            value = sum(map(float,c[1:]))/total_simdays
                        else:
                            value = sum(map(float,c[1:]))
                        res_list[srf_name] = value
            
                counter =+1
            return res_list
        #======================================================================
        if result_category == "sol_beam":
            counter = 0
            res_list ={}
            res_list["att_name"] ="Surface_Ext_Solar_Beam_Incident"
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Solar Beam Incident[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        if display == "daily":
                            value = sum(map(float,c[1:]))/total_simdays
                        else:
                            value = sum(map(float,c[1:]))
                            
                        res_list[srf_name] = value
            
                counter =+1
            return res_list
        #======================================================================
        if result_category == "sol_sky_diff":
            counter = 0
            res_list ={}
            res_list["att_name"] ="Surface_Ext_Solar_Sky_Diffuse_Incident"
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Solar Sky Diffuse Incident[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        if display == "daily":
                            value = sum(map(float,c[1:]))/total_simdays
                        else:
                            value = sum(map(float,c[1:]))
                        res_list[srf_name] = value
            
                counter =+1
            return res_list
        #======================================================================
        if result_category == "sol_refl_obs":
            
            counter = 0
            res_list1 =[]
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Solar Ground Diffuse Incident[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        att_name = c[0].split(":")[1].replace("(RunPeriod)", "")
                        value = sum(map(float,c[1:]))
                        result = {"srf_name":srf_name, "att_name":att_name, "value":value}
                        res_list1.append(result)
            
                counter =+1
                
            counter = 0
            res_list2 =[]
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Solar From Sky Diffuse Refl From Obstructions[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        att_name = c[0].split(":")[1].replace("(RunPeriod)", "")
                        value = sum(map(float,c[1:]))
                        result = {"srf_name":srf_name, "att_name":att_name, "value":value}
                        res_list2.append(result)
            
                counter =+1
                
            counter = 0
            res_list3 =[]
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Beam Sol From Bm-To-Bm Refl From Obstructions[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        att_name = c[0].split(":")[1].replace("(RunPeriod)", "")
                        value = sum(map(float,c[1:]))
                        result = {"srf_name":srf_name, "att_name":att_name, "value":value}
                        res_list3.append(result)
            
                counter =+1
                
            counter = 0
            res_list4 =[]
            for c in content:
                if counter !=0:
                    if c[0].split(":")[1] == "Surface Ext Diff Sol From Bm-To-Diff Refl From Obstructions[W/m2](RunPeriod)":
                        srf_name  = string.lower(c[0].split(":")[0])
                        att_name = c[0].split(":")[1].replace("(RunPeriod)", "")
                        value = sum(map(float,c[1:]))
                        result = {"srf_name":srf_name, "att_name":att_name, "value":value}
                        res_list4.append(result)
            
                counter =+1
                
            num_srf = len(res_list1)
            res_list = {}
            res_list["att_name"] ="Surface_Ext_Solar_Reflected_From_Obstruction"
            for cnt in range(num_srf):
                srf_name = res_list1[cnt]["srf_name"]
                value1 = res_list1[cnt]["value"]
                value2 = res_list2[cnt]["value"]
                value3 = res_list3[cnt]["value"]
                value4 = res_list4[cnt]["value"]
                value = value1 + value2 + value3 + value4 
                if display == "daily":
                    value = value/total_simdays
                res_list[srf_name] = value
                
            return res_list
            
        #======================================================================
        
class SimParm(object):
    def __init__(self, start_month, start_day, end_month, end_day, idf):
        self.s_mth = start_month
        self.s_day = start_day
        self.e_mth = end_month
        self.e_day = end_day
        idf.simparms.append(self)
        
    def idf(self):
        runperiod = energypluslink.write_ep_runperiod(self.s_mth, self.s_day, 
                                                      self.e_mth, self.e_day)
        return runperiod
    
class OutputMeter(object):
    def __init__(self, variable_name, report_frequency, idf):
        self.variable = variable_name
        self.frequency = report_frequency
        idf.outputmeter.append(self)
        
    def idf(self):
        output_meter = energypluslink.write_ep_outputmeter(self.variable, self.frequency)
        
        return output_meter
    
class OutputVariables(object):
    def __init__(self, variable_name, report_frequency, idf):
        self.variable = variable_name
        self.frequency = report_frequency
        idf.outputvars.append(self)
        
    def idf(self):
        output_var = energypluslink.write_ep_outputvar(self.variable, self.frequency)
        
        return output_var
    
class IdfZone(object):
    def __init__(self, name, idf):
        self.name = name
        self.Idf = idf
        self.surfaces = []
        self.subsurfaces = []
        idf.zones.append(self)
        
    def add_surface(self,  surface):
        surface.zone = self.name
        self.surfaces.append(surface)
        
    def add_window(self,  window):
        self.subsurfaces.append(window)
        
    def add_shade(self,  shade):
        self.subsurfaces.append(shade)
        
    def add_cool_schedule(self, start, end, temp):
        self.cstart = start
        self.cend = end
        self.ctemp = temp
        
    def add_heat_schedule(self, start, end, temp):
        self.hstart = start
        self.hend = end
        self.htemp = temp
        
    def add_hvac(self, template_name ):
        if self.cstart == None or self.hstart == None:
            raise Exception 
        self.hvac_name = template_name
        
    def add_light_schedule(self, start, end):
        self.l_start = start
        self.l_end = end 
        
    def add_light(self, light_name):
        if self.l_start == None:
            raise Exception
        self.light_name = light_name 
        
    def idf(self):
        name = self.name 
        zone_data = energypluslink.write_ep_zone(name)
        if self.hvac_name :
            hvac_name = self.hvac_name
            c_name = name+"cool"
            h_name = name+"heat"
            t_name = name+"thermo"
            c_schedule = energypluslink.write_ep_hvacschedule(c_name, self.cstart, 
                                                              self.cend, self.ctemp)
            
            h_schedule = energypluslink.write_ep_hvacschedule(h_name, self.hstart, 
                                                              self.hend, self.htemp)
            thermostat = energypluslink.write_ep_thermostat(t_name, h_name,
                                                             c_name)
            hvac = energypluslink.write_ep_hvac(hvac_name, name, t_name)
            zone_data = zone_data + c_schedule + h_schedule + thermostat + hvac
            
        if self.light_name :
            light_name = self.light_name 
            l_name = name + "light"
            l_schedule = energypluslink.write_ep_lightschedule(l_name, self.l_start,
                                                               self.l_end)
            
            light = energypluslink.write_ep_light(light_name, name, l_name )
            zone_data = zone_data + l_schedule + light
            
        return zone_data
        
class IdfZoneSurface(Surface):
    def __init__(self, name, points, material, type):
        super(IdfZoneSurface, self).__init__(name,  points, material)
        self.zone = None 
        self.boundary = "Outdoors" 
        self.boundary_obj = "" 
        self.sun_exp = "SunExposed" 
        self.win_exp = "WindExposed"
        self.type = type
        
    def idf(self):
        total_z=[]
        for point in self.points:
            total_z.append(point[2])
            
        if self.type == "Floor" and sum(total_z) == 0:
            self.boundary = "Ground"
            self.sun_exp =  "NoSun"
            self.win_exp = "NoWind"
            
        name = self.name
        type = self.type
        construction = self.material
        zone = self.zone
        boundary = self.boundary
        boundary_object = self.boundary_obj
        sun_exp = self.sun_exp
        wind_exp = self.win_exp
        points = self.points
        
        surface_data = energypluslink.write_ep_surface(name, type,construction, zone, 
                                                boundary,boundary_object, sun_exp, wind_exp, points)
        return surface_data
                                              
class IdfSubSurface(Surface):
    def __init__(self, name, points, material, host_srf):
        super(IdfSubSurface,self).__init__(name,  points, material)
        self.host_srf = host_srf
        self.transmittance = "" 

class IdfWindow(IdfSubSurface):
    
    def idf(self):
        if self.host_srf == None:
            raise Exception
        
        win_name = self.name 
        win_construction = self.material
        build_surface = self.host_srf
        win_shading = ""
        win_frame = ""
        win_points = self.points
        window_data = energypluslink.write_ep_window(win_name, win_construction, build_surface, win_shading, win_frame, win_points)   
        return window_data


class IdfShade(IdfSubSurface):
    
    def idf(self):
        if self.host_srf == None:
            raise Exception
        shade_name = self.name 
        base_surface = self.host_srf
        transmittance = self.transmittance
        shade_points = self.points
        shade_data = energypluslink.write_ep_zone_shade(shade_name, base_surface, transmittance, shade_points)
        return shade_data

#for shadings that are not attached to the buildings which includes trees and surrounding site
class IdfBuildingShade(object): 
    def __init__(self, name, points, idf):
        self.name = name 
        self.points = points
        idf.buildingshades.append(self)
        
    def idf(self):
        buildingshade_data = energypluslink.write_ep_building_shade(self.name, "", self.points)
        return buildingshade_data


